package com.jxm.channel;

import org.junit.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.charset.Charset;
import java.util.Random;
import java.util.UUID;

/**
 * @Author: jxm
 * @Description: 客户端发送，服务端接收的例子
 * @Date: 2024-2-7 15:43
 * @Version: 1.0
 */
public class DatagramChannelDemo {

    public void test() throws Exception{
        //1、打开 10086 端口接收 UDP 数据包
        DatagramChannel server = DatagramChannel.open();
        server.socket().bind(new InetSocketAddress(10086));

        //2、通过 receive()接收 UDP 包
        //SocketAddress 可以获得发包的 ip、端口等信息，用 toString 查看，格式如: 127.0.0.1:57126
        ByteBuffer receiveBuffer = ByteBuffer.allocate(64);
        receiveBuffer.clear();
        SocketAddress receiveAddr = server.receive(receiveBuffer);

        //3、通过 send()发送 UDP 包
        ByteBuffer sendBuffer = ByteBuffer.wrap("client send".getBytes());
        server.send(sendBuffer, new InetSocketAddress("127.0.0.1",10086));

        //4、连接
        //UDP 不存在真正意义上的连接，这里的连接是向特定服务地址用 read 和 write 接收发送数据包。
        /**
         * read()和 write()只有在 connect()后才能使用，不然会抛
         * NotYetConnectedException 异常。用 read()接收时，如果没有接收到包，会抛
         * PortUnreachableException 异常。
         */
        DatagramChannel client = DatagramChannel.open();
        client.connect(new InetSocketAddress("127.0.0.1",10086));
        int readSize= client.read(sendBuffer);
        server.write(sendBuffer);
    }

    @Test
    public void randomTest(){
        Random random = new Random();
        System.out.println(random.nextInt(10));
    }

    /**
     * 发送
     * @throws Exception
     */
    @Test
    public void sendDatagram() throws Exception {
        DatagramChannel sendChannel= DatagramChannel.open();
        InetSocketAddress sendAddress= new InetSocketAddress("127.0.0.1", 9999);
        while (true) {
            String content = "hello" + new Random().nextInt(10);
            sendChannel.send(ByteBuffer.wrap(content.getBytes("UTF-8")), sendAddress);
            System.out.println("发送内容:"+content);
            Thread.sleep(2000);
        }
    }

    /**
     * 收包端
     * @throws Exception
     */
    @Test
    public void receive() throws Exception {
        DatagramChannel receiveChannel= DatagramChannel.open();
        InetSocketAddress receiveAddress= new InetSocketAddress("127.0.0.1",9999);
        receiveChannel.bind(receiveAddress);

        ByteBuffer receiveBuffer= ByteBuffer.allocate(512);
        while (true) {
            receiveBuffer.clear();
            SocketAddress sendAddress= receiveChannel.receive(receiveBuffer);
            receiveBuffer.flip();
            System.out.print(sendAddress.toString() + " ");
            System.out.println(Charset.forName("UTF-8").decode(receiveBuffer));
        }
    }

    /**
     * 只接收和发送 9999 的数据包
     * @throws IOException
     */
    @Test
    public void testConnect1() throws IOException {
        DatagramChannel connChannel= DatagramChannel.open();
        connChannel.bind(new InetSocketAddress(9999));

        connChannel.connect(new InetSocketAddress("127.0.0.1",9999));
        //发送
        connChannel.write(ByteBuffer.wrap("发包".getBytes("UTF-8")));
        ByteBuffer readBuffer= ByteBuffer.allocate(512);
        while (true) {
            try {
                readBuffer.clear();
                //接收
                connChannel.read(readBuffer);
                readBuffer.flip();
                System.out.println(Charset.forName("UTF-8").decode(readBuffer));
            }catch(Exception e) {

            }
        }
    }
}
